/////////////////////////////////////////////////////
// File Name: switch_top_v1.v
// Author: zeping fan
// mail:   zpfan007@163.com
// Created Time: 2023年06月28日 星期三 22时41分04秒
/////////////////////////////////////////////////////

module  switch_top_v1#(
    parameter   PORT_NUM = 4
)(
clk,
rst_n,

//MII_RX interface
mii_rx_clk,
mii_rx_dv,
mii_rxd,
drop_num,

//MII_TX interface
mii_tx_clk,
mii_tx_en,
mii_txd
);

input                           clk;
input                           rst_n;

input   [PORT_NUM-1:0]          mii_rx_clk;
input   [PORT_NUM-1:0]          mii_rx_dv;
input   [PORT_NUM-1:0][3:0]     mii_rxd;  

input   [PORT_NUM-1:0]          mii_tx_clk;
output  [PORT_NUM-1:0]          mii_tx_en;
output  [PORT_NUM-1:0][3:0]     mii_txd;
output  [PORT_NUM-1:0][15:0]    drop_num;
//mac_r to frame_mux interface
wire    [PORT_NUM-1:0]          mac_r_ptr_fifo_rd;
wire    [PORT_NUM-1:0]          mac_r_ptr_fifo_empty;
wire    [PORT_NUM-1:0][15:0]    mac_r_ptr_fifo_dout;
wire    [PORT_NUM-1:0]          mac_r_data_fifo_rd;
wire    [PORT_NUM-1:0][7:0]     mac_r_data_fifo_dout;  

//frame_mux to frame_process interface
wire                            frame_mux_ptr_fifo_rd;
wire                            frame_mux_ptr_fifo_empty;
wire    [15:0]                  frame_mux_ptr_fifo_dout;
wire                            frame_mux_data_fifo_rd;
wire    [7:0]                   frame_mux_data_fifo_dout;

//frame_process to hash_lut interface
wire                            hash_lut_source;
wire                            hash_lut_req;
wire    [47:0]                  hash_lut_mac;
wire    [9:0]                   hash_lut_hash;
wire    [15:0]                  hash_lut_portmap;
wire                            hash_lut_ack;
wire                            hash_lut_nak;
wire    [15:0]                  hash_lut_result;

//frame_process to queue_manager interface
wire                            qm_sof;
wire                            qm_dv;
wire    [7:0]                   qm_data;
wire                            queue_process_bp;

//queue_manager to mac_t interface
wire    [PORT_NUM-1:0]          qm_ptr_fifo_rd;
wire    [PORT_NUM-1:0]          qm_ptr_fifo_empty;
wire    [PORT_NUM-1:0][15:0]    qm_ptr_fifo_dout;
wire    [PORT_NUM-1:0]          qm_data_fifo_rd;
wire    [PORT_NUM-1:0][7:0]     qm_data_fifo_dout;  


//============================Module instantiation============================
generate
genvar i;
for(i=0;i<PORT_NUM;i=i+1)begin: mac_rx_loop_gen
mac_r#(
    .DATA_FIFO_DEPTH(4096)
)
x_mac_r(
    .clk(clk),
    .rst_n(rst_n),
    .rx_clk(mii_rx_clk[i]),
    .rx_dv(mii_rx_dv[i]),
    .rx_d(mii_rxd[i]),
    .data_fifo_rd(mac_r_data_fifo_rd[i]),
    .data_fifo_dout(mac_r_data_fifo_dout[i]),
    .ptr_fifo_rd(mac_r_ptr_fifo_rd[i]),
    .ptr_fifo_dout(mac_r_ptr_fifo_dout[i]),
    .ptr_fifo_empty(mac_r_ptr_fifo_empty[i])
);
end
endgenerate

frame_mux #(
    .PORT_NUM(4),
    .DATA_FIFO_DEPTH(8192),
    .PTR_FIFO_DEPTH(32)
)
x_frame_mux(
    .clk(clk),
    .rst_n(rst_n),
    .mac_rx_ptr_fifo_empty(mac_r_ptr_fifo_empty),
    .mac_rx_ptr_fifo_rd(mac_r_ptr_fifo_rd),
    .mac_rx_ptr_fifo_dout(mac_r_ptr_fifo_dout),
    .mac_rx_data_fifo_rd(mac_r_data_fifo_rd),
    .mac_rx_data_fifo_dout(mac_r_data_fifo_dout),
    .frame_mux_ptr_fifo_empty(frame_mux_ptr_fifo_empty),
    .frame_mux_ptr_fifo_rd(frame_mux_ptr_fifo_rd),
    .frame_mux_ptr_fifo_dout(frame_mux_ptr_fifo_dout),
    .frame_mux_data_fifo_rd(frame_mux_data_fifo_rd),
    .frame_mux_data_fifo_dout(frame_mux_data_fifo_dout)
);


frame_process
x_frame_process(
    .clk(clk),
    .rst_n(rst_n),
    .frame_mux_ptr_fifo_empty(frame_mux_ptr_fifo_empty),
    .frame_mux_ptr_fifo_rd(frame_mux_ptr_fifo_rd),
    .frame_mux_ptr_fifo_dout(frame_mux_ptr_fifo_dout),
    .frame_mux_data_fifo_rd(frame_mux_data_fifo_rd),
    .frame_mux_data_fifo_dout(frame_mux_data_fifo_dout),
    .hash_lut_source(hash_lut_source),
    .hash_lut_req(hash_lut_req),
    .hash_lut_mac(hash_lut_mac),
    .hash_lut_hash(hash_lut_hash),
    .hash_lut_portmap(hash_lut_portmap),
    .hash_lut_ack(hash_lut_ack),
    .hash_lut_nak(hash_lut_nak),
    .hash_lut_result(hash_lut_result),
    .queue_process_bp(queue_process_bp),
    .queue_sof(qm_sof),
    .queue_dv(qm_dv),
    .queue_dout(qm_data)
);


hash_lut#(
    .TTL_NUM(300)
)
x_hash_lut(
    .clk(clk),
    .rst_n(rst_n),
    .se_source(hash_lut_source),
    .se_req(hash_lut_req),
    .se_mac(hash_lut_mac),
    .se_hash(hash_lut_hash),
    .se_portmap(hash_lut_portmap),
    .se_ack(hash_lut_ack),
    .se_nak(hash_lut_nak),
    .se_result(hash_lut_result),
    .aging_req(1'b0),
    .aging_ack()
);


queue_manager#(
    .PORT_NUM(4)
)
x_queue_manager(
    .clk(clk),
    .rst_n(rst_n),
    .sof(qm_sof),
    .dat_vld(qm_dv),
    .din(qm_data),
    .bp(queue_process_bp),
    .ptr_fifo_rd(qm_ptr_fifo_rd),
    .ptr_fifo_dout(qm_ptr_fifo_dout),
    .ptr_fifo_empty(qm_ptr_fifo_empty),
    .data_fifo_rd(qm_data_fifo_rd),
    .data_fifo_dout(qm_data_fifo_dout)
);


generate
genvar j;
for(j=0;j<PORT_NUM;j=j+1)begin: mac_tx_loop_gen
mac_t#(
    .DATA_FIFO_DEPTH(8192)
)
x_mac(
    .clk(clk),
    .rst_n(rst_n),
    .tx_clk(mii_tx_clk[j]),
    .tx_dv(mii_tx_en[j]),
    .tx_d(mii_txd[j]),
    .cnt_drop(drop_num[j]),
    .qm_dfifo_rd(qm_data_fifo_rd[j]),
    .qm_dfifo_dout(qm_data_fifo_dout[j]),
    .qm_pfifo_rd(qm_ptr_fifo_rd[j]),
    .qm_pfifo_empty(qm_ptr_fifo_empty[j]),
    .qm_pfifo_dout(qm_ptr_fifo_dout[j])
);
end
endgenerate

endmodule
